import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd

def draw_network_graph(G, step):
    # 设置颜色和粗细（权重）
    edge_colors = [
        'green' if G[u][v].get('status') == 'accepted' else 
        'red' if G[u][v].get('status') == 'rejected' else 
        'gray' if G[u][v].get('collaboration') else 
        'black'
        for u, v in G.edges()
    ]
    edge_weights = [
        G[u][v]['weight'] if not G[u][v].get('collaboration') else 1 
        for u, v in G.edges()
    ]

    # 设置节点颜色和大小
    node_colors = []
    node_sizes = []
    for node in G.nodes():
        if G.nodes[node].get('type') == 'rider':
            node_colors.append('skyblue')
            node_sizes.append(4000)  # 较大的骑手节点
        else:
            node_colors.append('orange')
            node_sizes.append(2000)  # 较小的订单节点

    # 绘制网络图
    pos = nx.spring_layout(G)  # 使用spring布局
    plt.figure(figsize=(10, 8))
    nx.draw(G, pos, with_labels=True, node_color=node_colors, edge_color=edge_colors, width=edge_weights, node_size=3000, font_size=10, font_weight='bold')
    plt.title(f'Step {step}')
    
    # 保存网络图
    plt.savefig(f'network_graph_step_{step}.png')
    plt.close()

def update_graph_data(G, riders, orders, interactions):
    """
    更新图 G 的数据，添加骑手节点和订单节点，并根据交互信息添加边。
    
    :param G: NetworkX 图对象
    :param riders: 骑手列表
    :param orders: 订单列表
    :param interactions: 每个交互由（骑手，订单/骑手，权重，状态）组成的元组列表
    """
    # 添加骑手节点
    for rider in riders:
        if rider not in G.nodes():
            G.add_node(rider, type='rider')

    # 添加订单节点
    for order in orders:
        if order not in G.nodes():
            G.add_node(order, type='order')

    # 添加交互边
    for interaction in interactions:
        G.add_edge(interaction[0], interaction[1], weight=interaction[2], status=interaction[3])

def update_analysis(G, step, csv_file, last_six_steps, degree_distributions):
    # 保持最近6步的数据
    if len(last_six_steps) >= 6:
        last_six_steps.pop(0)

    # 保存当前图的副本
    last_six_steps.append(G.copy())

    # 度分布
    degree_distribution = pd.Series(dict(G.degree()))
    degree_distributions[step] = degree_distribution.value_counts().sort_index()

    # 网络密度
    density = nx.density(G)

    # 强连通分量的平均最短路径长度
    strongly_connected_components = list(nx.strongly_connected_components(G))
    largest_scc = max(strongly_connected_components, key=len)
    subgraph = G.subgraph(largest_scc)
    avg_path_length = nx.average_shortest_path_length(subgraph)

    # 中心性：分析最有影响力的骑手节点
    degree_centrality = nx.degree_centrality(G)
    most_influential_riders = '; '.join(pd.Series(degree_centrality).nlargest(3).index)  # 使用分号分隔多个值

    # 连通分量：分析系统是否存在多个独立的子网络
    connected_components = list(nx.connected_components(G.to_undirected()))
    num_connected_components = len(connected_components)
    largest_cc_size = len(max(connected_components, key=len))

    # 将分析结果写入 CSV 文件，每次追加一行
    with open(csv_file, 'a') as f:
        f.write(f"{step},{density},{avg_path_length},{most_influential_riders},{num_connected_components},{largest_cc_size}\n")

    return last_six_steps, degree_distributions

# 绘制和保存度分布的变化图
def save_degree_distribution_plot(degree_distributions):
    plt.figure(figsize=(12, 8))
    for step, dist in degree_distributions.items():
        plt.plot(dist.index, dist.values, marker='o', label=f'Step {step}')
    plt.title("Degree Distribution Over Steps")
    plt.xlabel("Degree")
    plt.ylabel("Frequency")
    plt.legend()
    plt.savefig('Degree_distribution_over_steps.png')
    plt.close()  # Close the figure to prevent overwriting issues

# def system_step(step, interactions):
#     riders = ['Rider A', 'Rider B', 'Rider C']
#     orders = ['Order 1', 'Order 2', 'Order 3', 'Order 4', 'Order 5']

#     # 更新图数据
#     update_graph_data(G, riders, orders, interactions)
    
#     # 更新分析数据并保存图的状态
#     update_analysis(G, step)

# # 首次运行时，创建 CSV 文件并写入表头
# csv_file = 'network_analysis_results.csv'
# with open(csv_file, 'w') as f:
#     f.write("Step,Network Density,Average Path Length (SCC),Most Influential Riders,Number of Connected Components,Size of Largest Component\n")

# # 执行系统的多个步骤
# for i in range(8):
#     system_step(i, [('Rider A', 'Order 1', 2, 'accepted'), ('Rider C', 'Order 5', 2, 'rejected'), ('Rider A', 'Rider B', 1, 'collaboration')])

# # 仅绘制并保存最后6步的图
# for i, graph in enumerate(last_six_steps):
#     draw_network_graph(graph, len(last_six_steps) - 6 + i)

# # 保存度分布变化图
# save_degree_distribution_plot()
